#include "stdafx.h"
#include "XLinkImpl.h"

#include "Util.h"
#include "UIUtil.h"

#include "IntSkinImpl.h"
#include "UIDefaultValue.h"
#include "ServiceUtil.h"

template <class I>
CXLinkImpl<I>::CXLinkImpl()
{
    m_bLinkMode = FALSE;
    ModifyControlFlags(ESkin_CanHover, TRUE);
    ModifyControlFlags(ESkin_Interactive, TRUE);
#if _IS_UI_FOCUS_ENABLED_
    ModifyControlFlags(ESkin_NeedKeyMsg, TRUE);
#endif // _IS_UI_FOCUS_ENABLED_
    SetCursor(IDC_HAND);

    m_clrHover = XDEFAULT_LINK_TEXT_COLOR;
    m_TextParser.SetUnderlineColor(TRUE, m_clrHover);
}

template <class I>
CXLinkImpl<I>::~CXLinkImpl()
{
}

//////////////////////////////////////////////////////////////////////////
// IXLink
template <class I>
HRESULT CXLinkImpl<I>::put_Link(IN LPCTSTR szLink)
{
    m_bLinkMode = TRUE;
    IntSkinImpl::SetorLoadStringSaveResId(szLink, m_strLink, m_strLinkResId);
    return S_OK;
}

template <class I>
HRESULT CXLinkImpl<I>::get_Link(IN BSTR* bstrLink)
{
    return (::SysReAllocString(bstrLink, m_strLink.GetData()) != FALSE);
}

template <class I>
void CXLinkImpl<I>::put_NormalColor(IN COLORREF clrNormal)
{
    UIUtil::XGetTextEnv(this)->put_TextColor(clrNormal);
    Invalidate();
}

template <class I>
COLORREF CXLinkImpl<I>::get_NormalColor()
{
    return UIUtil::XGetTextEnv(this)->get_TextColor();
}

template <class I>
void CXLinkImpl<I>::put_HoverColor(IN COLORREF clrHover)
{
    m_clrHover = clrHover;
    m_TextParser.SetUnderlineColor(TRUE, clrHover);
    Invalidate();
}

template <class I>
COLORREF CXLinkImpl<I>::get_HoverColor()
{
    return m_clrHover;
}

template <class I>
void CXLinkImpl<I>::put_AllColor(IN COLORREF clrAll)
{
    put_NormalColor(clrAll);
    put_HoverColor(clrAll);
}

template <class I>
HRESULT CXLinkImpl<I>::put_LinkMode(IN BOOL bLinkMode)
{
    m_bLinkMode = bLinkMode;
    return S_OK;
}

template <class I>
BOOL CXLinkImpl<I>::get_LinkMode()
{
    return m_bLinkMode;
}

template <class I>
HRESULT CXLinkImpl<I>::put_ShowUnderline(IN BOOL bShow)
{
    if((!!m_bShowUnderLine) != (!!bShow))
    {
        m_bShowUnderLine = bShow;
        Invalidate();
    }
    return S_OK;
}

template <class I>
BOOL CXLinkImpl<I>::get_ShowUnderline()
{
    return m_bShowUnderLine;
}

//////////////////////////////////////////////////////////////////////////
// IXFrame
template <class I>
void CXLinkImpl<I>::GetAutoSize(OUT LPSIZE pAutoSize)
{
    superclass::GetAutoSize(pAutoSize);
    pAutoSize->cy += 2;
}

template <class I>
void CXLinkImpl<I>::Draw(XCANVAS xCanvas, const RECT& rcDraw)
{
    BOOL bHover = TestControlFlags(ESkin_Hover);
    DWORD dwTextColor = 0;

    IXTextEnv* pTextEnv = NULL;
    if(bHover)
    {
        pTextEnv = UIUtil::XGetTextEnv(this);
        dwTextColor = pTextEnv->get_TextColor();
        pTextEnv->put_TextColor(m_clrHover);
    }

    superclass::Draw(xCanvas, rcDraw);

    if(bHover)
    {
        UIUtil::XGetTextEnv(this)->put_TextColor(dwTextColor);
    }
}

template <class I>
BOOL CXLinkImpl<I>::OnMouseHover(IN POINT* pt)
{
    superclass::OnMouseHover(pt);

    if(m_bRichText)
    {
        if(m_bShowUnderLine)
            m_TextParser.SetUnderLine(TRUE);
        Invalidate();
    }
    else
    {
        IXFont* pFont = NULL;
        get_Font(&pFont);
        if(pFont != NULL)
        {
            if(m_bShowUnderLine)
                pFont->put_Underline(TRUE);
            Invalidate();
        }
    }
    return TRUE;
}

template <class I>
BOOL CXLinkImpl<I>::OnMouseLeave(IN POINT* pt)
{
    superclass::OnMouseLeave(pt);

    if(m_bRichText)
    {
        m_TextParser.SetUnderLine(FALSE);
        Invalidate();
    }
    else
    {
        IXFont* pFont = NULL;
        get_Font(&pFont);
        if(pFont != NULL)
        {
            pFont->put_Underline(FALSE);
            Invalidate();
        }
    }
    return TRUE;
}

template <class I>
BOOL CXLinkImpl<I>::OnMouseUp(IN POINT* pt)
{
    superclass::OnMouseUp(pt);

    if(m_bLinkMode)
    {
        LPCTSTR szLink = m_strLink.empty() ? m_strText.GetData() : m_strLink.GetData();
        ServiceUtil::OpenUrl(szLink);
    }
    return TRUE;
}

//////////////////////////////////////////////////////////////////////////
// CXControlImpl
template <class I>
HRESULT CXLinkImpl<I>::OnSkinLangChanged()
{
    superclass::OnSkinLangChanged();
    XString strLink;
    XString strLinkResId = m_strLinkResId;
    if(IntSkinImpl::ReLoadString(m_strLinkResId.c_str(), strLink))
    {
        put_Link(strLink.c_str());
        m_strLinkResId = strLinkResId;
    }
    return S_OK;
}
